package pt.compflow.activity.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pt.compflow.Context;
import pt.compflow.flowontology.model.Assignment;
import pt.compflow.flowontology.model.FlowOntologyModel;
import pt.compflow.flowontology.model.Task;
import pt.compflow.flowontology.model.Worker;
import pt.compflow.flowontology.model.Workflow;
import pt.compflow.interfaces.IOInterface;
import pt.compflow.interfaces.task.TaskInterface;
import pt.compflow.storage.TripleStoreConnection;
import pt.compflow.tools.OntModelHelper;

/**
 * TaskController Command to request an Assignment to a Worker through a TaskInterface
 * 
 */
public class TaskControllerRequestAssignmentCommand implements Runnable {

	private static final Logger LOG = LoggerFactory.getLogger(TaskControllerRequestAssignmentCommand.class);

	protected TaskControllerImpl taskController;
	protected IOInterface taskInterface;
	protected String jobUri;
	protected String taskUri;
	protected String assignmentUri;
	protected String workerUri;
	protected Context context;

	public TaskControllerRequestAssignmentCommand(Context context, TaskControllerImpl taskController, IOInterface taskInterface, String jobUri, String taskUri, String assignmentUri, String workerUri) {
		this.taskController = taskController;
		this.taskInterface = taskInterface;
		this.jobUri = jobUri;
		this.taskUri = taskUri;
		this.assignmentUri = assignmentUri;
		this.workerUri = workerUri;
		this.context = context;
	}

	@Override
	public void run() {
		LOG.debug("Requesting Assignment " + assignmentUri + " by Worker " + workerUri + " through Interface " + taskInterface.getInterfaceUri());
		
		TripleStoreConnection store = context.getStoreConnection();
		store.openStore();

		try {
			FlowOntologyModel engineModel = store.connectModel();
			FlowOntologyModel jobModel = store.connectNamedModel(jobUri);
			
			Task t = jobModel.getTaskWithURI(taskUri);
			Workflow wf = t.getActivityOfWorkflow();
			Worker w = engineModel.getWorkerWithURI(workerUri);
			
			Assignment a = jobModel.getAssignmentWithURI(assignmentUri);
						
			// get the ontology model (workflow-definition) of this workflow
			OntModelHelper ontModelHelper = context.getOntModelHelperManager().get(store, jobUri, wf.getRootWorkflow().getLocalName());
			
			// request the assignment a from worker w through the taskInterface
			((TaskInterface) taskInterface).request(context, store, ontModelHelper, jobModel, engineModel, jobUri, w, a);

		} catch (Throwable e) {
			LOG.error("Error trying to request Assignment " + assignmentUri + " for Task " + taskUri, e);
			taskController.onCommandError(jobUri, taskUri, taskInterface.getInterfaceUri());
		}
		
		store.closeStore();
	}

}
